/*
Copyright [2023] [fuwen_soft]
*/
package vip.xiaonuo.modular.xylogy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import vip.xiaonuo.core.context.login.LoginContextHolder;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.util.PoiUtil;
import vip.xiaonuo.modular.xyethnic.service.XyEthnicService;
import vip.xiaonuo.modular.xylogy.entity.XyLogy;
import vip.xiaonuo.modular.xylogy.enums.XyLogyExceptionEnum;
import vip.xiaonuo.modular.xylogy.form.*;
import vip.xiaonuo.modular.xylogy.mapper.XyLogyMapper;
import vip.xiaonuo.modular.xylogy.param.XyLogyParam;
import vip.xiaonuo.modular.xylogy.service.XyLogyService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.modular.xylogyauth.entity.XyLogyAuth;
import vip.xiaonuo.modular.xylogyauth.service.XyLogyAuthService;
import vip.xiaonuo.modular.xylogylogs.service.XyLogyLogsService;
import vip.xiaonuo.modular.xyrule.service.XyRuleService;
import vip.xiaonuo.modular.xyuser.entity.XyUser;
import vip.xiaonuo.modular.xyuser.service.XyUserService;

import java.util.List;
import java.util.Objects;

import static vip.xiaonuo.modular.xylogy.enums.XyLogyAuthEnum.ALL_AUTH;
import static vip.xiaonuo.modular.xyrule.constant.RuleConstant.MAX_CREATE_LOGY;

/**
 * 族谱书service接口实现类
 *
 * @author yanwei
 * @date 2023-05-05 15:44:28
 */
@Service
public class XyLogyServiceImpl extends ServiceImpl<XyLogyMapper, XyLogy> implements XyLogyService {

    @Autowired
    private XyRuleService xyRuleService;

    @Autowired
    private XyLogyAuthService xyLogyAuthService;

    @Autowired
    private XyEthnicService ethnicService;

    @Autowired
    private XyLogyLogsService xyLogyLogsService;

    @Autowired
    private XyUserService xyUserService;

    @Override
    public PageResult<XyLogy> page(XyLogyParam xyLogyParam) {
        QueryWrapper<XyLogy> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(xyLogyParam)) {

            // 根据用户编号,创建人 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getUserId())) {
                queryWrapper.lambda().eq(XyLogy::getUserId, xyLogyParam.getUserId());
            }
            // 根据家谱封面 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getLogyPic())) {
                queryWrapper.lambda().eq(XyLogy::getLogyPic, xyLogyParam.getLogyPic());
            }
            // 根据家族姓氏 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getLogyName())) {
                queryWrapper.lambda().eq(XyLogy::getLogyName, xyLogyParam.getLogyName());
            }
            // 根据姓氏 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getSurname())) {
                queryWrapper.lambda().eq(XyLogy::getSurname, xyLogyParam.getSurname());
            }
            // 根据始迁祖名 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getSourceName())) {
                queryWrapper.lambda().eq(XyLogy::getSourceName, xyLogyParam.getSourceName());
            }
            // 根据所属地区 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getAddrInfo())) {
                queryWrapper.lambda().eq(XyLogy::getAddrInfo, xyLogyParam.getAddrInfo());
            }
            // 根据模板序号 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getTemplateHost())) {
                queryWrapper.lambda().eq(XyLogy::getTemplateHost, xyLogyParam.getTemplateHost());
            }
            // 根据1=公开,2=私密 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getIsOpen())) {
                queryWrapper.lambda().eq(XyLogy::getIsOpen, xyLogyParam.getIsOpen());
            }
            // 根据is_open=2 有用，查看家谱密码 查询
            if (ObjectUtil.isNotEmpty(xyLogyParam.getLookPass())) {
                queryWrapper.lambda().eq(XyLogy::getLookPass, xyLogyParam.getLookPass());
            }
        }
        return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
    }

    @Override
    public List<XyLogy> list(XyLogyParam xyLogyParam) {
        return this.list();
    }

    @Override
    public void add(XyLogyParam xyLogyParam) {
        XyLogy xyLogy = new XyLogy();
        BeanUtil.copyProperties(xyLogyParam, xyLogy);
        this.save(xyLogy);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<XyLogyParam> xyLogyParamList) {
        xyLogyParamList.forEach(xyLogyParam -> {
            this.removeById(xyLogyParam.getId());
        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(XyLogyParam xyLogyParam) {
        XyLogy xyLogy = this.queryXyLogy(xyLogyParam);
        BeanUtil.copyProperties(xyLogyParam, xyLogy);
        this.updateById(xyLogy);
    }

    @Override
    public XyLogy detail(XyLogyParam xyLogyParam) {
        return this.queryXyLogy(xyLogyParam);
    }

    /**
     * 获取族谱书
     *
     * @author yanwei
     * @date 2023-05-05 15:44:28
     */
    private XyLogy queryXyLogy(XyLogyParam xyLogyParam) {
        XyLogy xyLogy = this.getById(xyLogyParam.getId());
        if (ObjectUtil.isNull(xyLogy)) {
            throw new ServiceException(XyLogyExceptionEnum.NOT_EXIST);
        }
        return xyLogy;
    }

    @Override
    public void export(XyLogyParam xyLogyParam) {
        List<XyLogy> list = this.list(xyLogyParam);
        PoiUtil.exportExcelWithStream("SnowyXyLogy.xls", XyLogy.class, list);
    }

    /**
     * 开始创建族谱
     * @param logyForm
     */
    @Override
    public void createLogy(LogyForm logyForm) {
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        XyUser xyUser = xyUserService.getById(userId);
        // 是否是族谱
        XyLogy xyLogy = getById(logyForm.getId());
        if (Objects.isNull(xyLogy)){
            Integer maxLogy = xyRuleService.getVal(MAX_CREATE_LOGY, Integer.class);
            int count = count(Wrappers.<XyLogy>lambdaQuery().eq(XyLogy::getUserId, userId));
            Assert.isTrue(maxLogy > count,"您已超过创建最大上限!");
            // 开始创建族谱
             xyLogy = new XyLogy(userId, logyForm);
            save(xyLogy);
            // 初始化族谱权限
            xyLogyAuthService.save(new XyLogyAuth(ALL_AUTH,userId,xyUser.getPhoneNumber(),xyLogy.getId(),1));
            // 初始化始组
            ethnicService.initSource(xyLogy,userId);
            xyLogyLogsService.saveLogyLog(userId,xyLogy.getId(),StrUtil.format("创建了新的族谱,{}",xyLogy.getLogyName()));
        }else{
            // 修改
            BeanUtil.copyProperties(logyForm,xyLogy);
            updateById(xyLogy);
            xyLogyLogsService.saveLogyLog(userId,xyLogy.getId(),StrUtil.format("修改了当前族谱信息,{}",xyLogy.getLogyName()));
        }

    }


    // 是否有绝对权限?
    @Override
    public void isAllAuthException(String userId, String logyId){
        XyLogyAuth logyAuth = xyLogyAuthService.getOne(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getDisabled, 1).eq(XyLogyAuth::getLogyId, logyId).eq(XyLogyAuth::getUserId, userId));
        Assert.isTrue(ALL_AUTH.getAuthP().equals(logyAuth.getPerMisc()),"暂无此权限!");

    }

    /**
     * 协作修家谱
     * @param logyAuthForm
     */
    @Override
    public void authLogys(LogyAuthForm logyAuthForm) {
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        isAllAuthException(userId,logyAuthForm.getLogyId());
        String remark = logyAuthForm.getRemark();
        // 查看 当前手机号是否绑定是同一个家谱
        XyUser xyUser = xyUserService.getById(userId);
        ///Assert.isFalse(xyUser.getPhoneNumber().equals(logyAuthForm.getPhone()),"不可改变自身权限!");
        // 查询下当前这个用户是否存在 如果存在直接绑定，如果不存在那么后埋雷即可
        XyUser serviceOne = xyUserService.getOne(Wrappers.<XyUser>lambdaQuery().eq(XyUser::getPhoneNumber, logyAuthForm.getPhone()));
        if (Objects.isNull(serviceOne)){
            // 如果不存在那么后埋雷即可
            xyLogyAuthService.remove(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getPhone,logyAuthForm.getPhone()));
            xyLogyAuthService.save(new XyLogyAuth(StrUtil.join(",",logyAuthForm.getEthnicIds()),remark,null,logyAuthForm.getPhone(),logyAuthForm.getLogyId(),1,"未注册"));

        }else{
            xyLogyAuthService.remove(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getPhone,logyAuthForm.getPhone()));
          //如果存在
           xyLogyAuthService.save(new XyLogyAuth(StrUtil.join(",",logyAuthForm.getEthnicIds()),remark,serviceOne.getId(),logyAuthForm.getPhone(),logyAuthForm.getLogyId(),1,"注册"));
        }

//        XyLogyAuth logyAuth = xyLogyAuthService.getOne(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getDisabled, 1).eq(XyLogyAuth::getLogyId, logyId).eq(XyLogyAuth::getUserId, userId));


    }

    @Override
    public void privateData(LogyPrivateForm logyPrivateForm) {
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        isAllAuthException(userId,logyPrivateForm.getLogyId());
        XyLogy logy = getById(logyPrivateForm.getLogyId());
        logy.setIsOpen(logyPrivateForm.getIsOpen());
        // 如果是公开就每必要了
        Assert.isTrue(Integer.valueOf(2).equals(logyPrivateForm.getIsOpen()) && StrUtil.isNotBlank(logyPrivateForm.getLookPass()),"设置私密,必须设置查看密码!");
        logy.setLookPass(logyPrivateForm.getLookPass());
        updateById(logy);
    }

    @Override
    public void editAuth(LogyEditAuthForm logyEditAuthForm) {
        XyLogyAuth byId = xyLogyAuthService.getById(logyEditAuthForm.getId());
        byId.setPerMisc(StrUtil.join(",",logyEditAuthForm.getEthnicIds()));
        xyLogyAuthService.updateById(byId);
    }

    @Override
    public void authLogysNew(LogyAuthNewForm logyAuthForm) {
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        isAllAuthException(userId,logyAuthForm.getLogyId());
        String remark = logyAuthForm.getRemark();
        // 查看 当前手机号是否绑定是同一个家谱
        XyUser xyUser = xyUserService.getById(userId);
        Assert.isFalse(logyAuthForm.getPhone().equals(xyUser.getPhoneNumber()),"不可改变自身权限!");
        // 查询下当前这个用户是否存在 如果存在直接绑定，如果不存在那么后埋雷即可
        XyUser serviceOne = xyUserService.getOne(Wrappers.<XyUser>lambdaQuery().eq(XyUser::getPhoneNumber, logyAuthForm.getPhone()));
        if (Objects.isNull(serviceOne)){
            // 如果不存在那么后埋雷即可
            xyLogyAuthService.remove(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getPhone,logyAuthForm.getPhone()));
            xyLogyAuthService.save(new XyLogyAuth(logyAuthForm.tranF(),remark,null,logyAuthForm.getPhone(),logyAuthForm.getLogyId(),1,"未注册"));

        }else{
            xyLogyAuthService.remove(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getPhone,logyAuthForm.getPhone()));
            //如果存在
            xyLogyAuthService.save(new XyLogyAuth(logyAuthForm.tranF(),remark,serviceOne.getId(),logyAuthForm.getPhone(),logyAuthForm.getLogyId(),1,"注册"));
        }

//        XyLogyAuth logyAuth = xyLogyAuthService.getOne(Wrappers.<XyLogyAuth>lambdaQuery().eq(XyLogyAuth::getDisabled, 1).eq(XyLogyAuth::getLogyId, logyId).eq(XyLogyAuth::getUserId, userId));

    }

    @Override
    public void editAuthNew(LogyEditAuthNewForm logyEditAuthForm) {
        XyLogyAuth byId = xyLogyAuthService.getById(logyEditAuthForm.getId());
        byId.setPerMisc(logyEditAuthForm.tranF());
        xyLogyAuthService.updateById(byId);
    }


}
